package swagger2.handler;

import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ValidationException;

@ResponseBody
@ControllerAdvice(annotations = RestController.class)
public class ApiExceptionAdvice
{

	private static org.slf4j.Logger logger = LoggerFactory.getLogger(ApiExceptionAdvice.class);

	/**
	 * 400 - Bad Request
	 */
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(BindException.class)
	public ApiResult handleBindException(BindException e)
	{
		logger.error("参数验证失败" + e.getMessage());
		return new ApiResult().failure("参数验证失败" + e.getMessage());
	}

	/**
	 * 400 - Bad Request
	 */
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(ValidationException.class)
	public ApiResult handleValidationException(ValidationException e)
	{
		logger.error("参数验证失败" + e.getMessage());
		return new ApiResult().failure("参数验证失败");
	}

	/**
	 * 400 - Bad Request
	 */
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public ApiResult handleHttpMessageNotReadableException(HttpMessageNotReadableException e)
	{
		logger.error("参数解析失败" + e.getMessage());
		return new ApiResult().failure("参数解析失败");
	}

	/**
	 * 405 - Method Not Allowed
	 */
	@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	public ApiResult handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e,
		HttpServletRequest request)
	{
		logger.error("不支持当前请求方法" + e.getMessage());
		return new ApiResult().failure(String.format("不支持%s请求方式", request.getMethod()));
	}

	/**
	 * 415 - Unsupported Media Type
	 */
	@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
	@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
	public ApiResult handleHttpMediaTypeNotSupportedException(Exception e)
	{
		logger.error("不支持当前媒体类型" + e.getMessage());
		return new ApiResult().failure("不支持当前媒体类型");
	}

	/**
	 * 403 -- FORBIDDEN
	 */
	@ResponseStatus(HttpStatus.FORBIDDEN)
	@ExceptionHandler(TokenException.class)
	public ApiResult handleHttpForbiddenException(Exception e)
	{
		logger.error("需要授权Token");
		return new ApiResult().failure(e.getMessage());
	}

	/**
	 * 404 - Not Found
	 */
	@ResponseStatus(HttpStatus.NOT_FOUND)
	@ExceptionHandler(NoHandlerFoundException.class)
	public ApiResult handleNoHandlerFoundException(NoHandlerFoundException e)
	{
		logger.error("资源不存在" + e.getMessage());
		return new ApiResult().failure("资源不存在");
	}

	/**
	 * 500 - NullPointerException Server Error
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(NullPointerException.class)
	public ApiResult handleNullPointerException(NullPointerException e)
	{
		logger.error("空指针异常", e);
		return new ApiResult().failure("空指针异常");
	}

	/**
	 * 500 - Internal Server Error
	 */
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(Exception.class)
	public ApiResult handleException(Exception e)
	{
		logger.error("服务运行异常," + e.getMessage(), e);
		return new ApiResult().failure(e.getMessage());
	}
}
